/*
 * 本example主要是用来展示如何使用DGGSField库实现对栅格类型数据的管理和组织
 * 本example只针对六边形格元的GridTIFF格式
 * 主要使用到DGGSFieldLayer.hpp、DGGSFieldBand.hpp、DGGSFieldPartition.hpp
 * DGGSField库支队用户开放DGGSFieldLayer.hpp、DGGSFieldBand.hpp两个头文件，使用时仅可在layer和band层级上操作，但内部含有partition故需要包含DGGSFieldPartition.hpp头文件
 * 本example依赖于kernel库
 * */

#include <stdexcept>
#include"DGGSFieldLayer.hpp"
#include"DGGSFieldBand.hpp"
#include"DGGSFieldPartition.hpp"

// 本样例使用的类及其方法均定义在NNU::DGGS::Field命令空间内
// 基础的数据结构定义在NNU::DGGS::Base命名空间内
using namespace NNU::DGGS::Field;
using namespace NNU::DGGS::Base;


/// <summary>
/// 创建一个field的图层
/// </summary>
/// <param name="bandCount">波段数</param>
/// <param name="dataType">数据类型</param>
/// <param name="elementType">要素类型</param>
/// <param name="gridType">格网类型</param>
/// <param name="level">层级</param>
/// <param name="bound">边界四至（依次为上下左右）</param>
template<class T>
DGGSFieldLayer<T> createFieldLayer(int bandCount,DGGSDataType dataType,DGGSElementType elementType,DGGSGridType gridType,int level,double*bound)
{
    switch (dataType) {
        case DGGS_UInt16:
            if constexpr (std::is_same<T, unsigned short>::value) {
                return DGGSFieldLayer<unsigned short>(bandCount, dataType, elementType, gridType, level, bound);
            } else {
                throw std::runtime_error("Type mismatch: Expected unsigned short");
            }
        case DGGS_Int16:
            if constexpr (std::is_same<T, short>::value) {
                return DGGSFieldLayer<short>(bandCount, dataType, elementType, gridType, level, bound);
            } else {
                throw std::runtime_error("Type mismatch: Expected short");
            }
        case DGGS_UInt32:
            if constexpr (std::is_same<T, unsigned int>::value) {
                return DGGSFieldLayer<unsigned int>(bandCount, dataType, elementType, gridType, level, bound);
            } else {
                throw std::runtime_error("Type mismatch: Expected unsigned int");
            }
        case DGGS_Int32:
            if constexpr (std::is_same<T, int>::value) {
                return DGGSFieldLayer<int>(bandCount, dataType, elementType, gridType, level, bound);
            } else {
                throw std::runtime_error("Type mismatch: Expected int");
            }
        case DGGS_Float32:
            if constexpr (std::is_same<T, float>::value) {
                return DGGSFieldLayer<float>(bandCount, dataType, elementType, gridType, level, bound);
            } else {
                throw std::runtime_error("Type mismatch: Expected float");
            }
        case DGGS_Float64:
            if constexpr (std::is_same<T, double>::value) {
                return DGGSFieldLayer<double>(bandCount, dataType, elementType, gridType, level, bound);
            } else {
                throw std::runtime_error("Type mismatch: Expected double");
            }
        default:
            throw std::runtime_error("Unsupported data type");
    }
}

/// <summary>
/// 修改指定波段某一位置数据
/// </summary>
/// <param name="fieldLayer">field图层对象</param>
/// <param name="location">格网编码指定位置</param>
/// <param name="value">属性值</param
/// <param name="bandId">波段id</param
template<class T>
bool updateValue(DGGSFieldLayer<T> fieldLayer, DGGSElementCode location,T value, int bandId)
{
    return fieldLayer.setValue(location,value,bandId);
}


/// <summary>
/// 修改指定波段某一位置数据
/// </summary>
/// <param name="fieldLayer">field图层对象</param>
/// <param name="location">经纬度指定位置</param>
/// <param name="value">属性值</param
/// <param name="bandId">波段id</param
template<class T>
bool updateValue(DGGSFieldLayer<T> &fieldLayer, GeoCoord location, T value, int bandId)
{
    return fieldLayer.setValue(location,value,bandId);
}


/// <summary>
/// 获取指定波段某一位置数据
/// </summary>
/// <param name="fieldLayer">field图层对象</param>
/// <param name="location">格网编码指定位置</param>
/// <param name="bandId">波段id</param
template<class T>
T findValue(DGGSFieldLayer<T> fieldLayer, DGGSElementCode location, int bandId)
{
    return fieldLayer.getValue(location,bandId);
}


/// <summary>
/// 查找指定波段某一位置数据
/// </summary>
/// <param name="fieldLayer">field图层对象</param>
/// <param name="location">经纬度指定位置</param>
/// <param name="bandId">波段id</param
template<class T>
T findValue (DGGSFieldLayer<T> &fieldLayer, GeoCoord location, int bandId)
{
    return fieldLayer.getValue(location,bandId);
}



int main()
{
    int bandCount=2;
    DGGSDataType dataType=DGGS_Float32;
    DGGSElementType elementType=DGGSElementType::Cell;
    DGGSGridType gridType=DGGSGridType::DGGS_ISEA4H;
    int level=5;
    auto bound=new double[4];
    bound[0]=90;
    bound[1]=-90;
    bound[2]=-180;
    bound[3]=180;


    // 创建field图层类
    auto fieldLayer=createFieldLayer<float>( bandCount, dataType, elementType, gridType, level,bound);

    //更新
    GeoCoord coord{45, 25};
    float value = 11;
    updateValue(fieldLayer,coord,value,1);

    //查找
    float newValue=findValue(fieldLayer,coord,1);

    return 0;
}